#include "gen_game_state.h"
#include "build.h"
#include "mat_ui_popupanimator.h"
#include "mat_ui_helper.h"
#include "mat_sfx_manager.h"
#include "mat_gamerule.h"
#include "mat_tutorial.h"
#include "mat_animation_mgr.h"

#include "bones/biped_anim.h"
#include "gameflow/ui_popup.h"
#include "ui/ui_progress.h"
#include "gameflow/ui_popup.h"
#include "background/bg_editor.h"	// new luabind can't forward define returned types.
#include "background/bg_scene.h"	
#include "application/game_application.h"

#include "dd/dd_man.h"
#include "ui/ui_manager.h"
#include "gameflow/game_flow_manager.h"
#include "script/scripthelper.h"

#include "font/font_manager.h"

			// log
#include "resman/resman.h"				// log

#include "util/timer.h"				
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif

#include <cassert>

using namespace script;

GENGameState::GENGameState(camera::FbCamera*	pCamera, const std::string& UI, const std::string& OnEnter, const std::string& OnExit ) :
	gameflow::UIState(pCamera, UI, OnEnter, OnExit),	
	m_IsDebugging(false),
	m_IsConstantScreenShot(false),
	m_ConstantScreenShotIndex(0),
	m_ToSkipConstantScreenShot(false),
	m_FPS(0),
	m_FPSTemp(0),
	m_IsLoaded(false),
	m_pGame(NULL)	
{	
	 
	//StartLevel("foo.lua");
	SetWidgetFunctor("pause_play",UI_DELEGATE(GENGameState, OnButtonPause));
	SetWidgetFunctor("button_show_achievement",UI_DELEGATE(GENGameState, OnButtonAchievement));
	
	m_pButtons.push_back(new MATUIHelper(GetWidget("pause_play")));
	//m_pButtons.push_back(new MATUIHelper(GetWidget("button_show_achievement")));	
	MATUIHelper::ResizeToCurentAspectRatio(GetWidget("pos_chest"));
	MATUIHelper::ResizeToCurentAspectRatio(GetWidget("gem_1"));
	MATUIHelper::ResizeToCurentAspectRatio(GetWidget("gem_2"));
	m_FPSCounter.SetLimit(1.0f);

		
}

GENGameState::~GENGameState()
{
	for(int i = 0; i < (int)m_pButtons.size(); i++)
	{
		UTIL_SAFE_DELETE(m_pButtons[i]);
	}
	m_pButtons.resize(0);

	UTIL_SAFE_DELETE(m_pGame);
	
}


bool	GENGameState::OnEnter()
{
	if(!m_IsLoaded)
	{
		m_pGame = new MATGame();		
		m_pGame->SetBackGround();
		// force animations to load here
		bones::BipedAnimationSet::Instance();
		bones::BipedAnimationSet::Instance().AddAnimationLua("anim/idle.sbp");
		bones::BipedAnimationSet::Instance().AddAnimationLua("anim/laugh.sbp");
		bones::BipedAnimationSet::Instance().AddAnimationLua("anim/surprised.sbp");
		m_IsLoaded = true;
	}

	MATSFXManager::Instance().ForceFinish();

	if(!m_FileToLoad.empty() && m_pGame)
	{
		m_pGame->Load(m_FileToLoad);
		m_FileToLoad = "";
	}

	return gameflow::UIState::OnEnter();
}
bool	GENGameState::OnExit()
{
	if(m_pGame)
		m_pGame->ClearRenderList();

	if(MATGameRule::Instance().GetTutorial())
		MATGameRule::Instance().GetTutorial()->ForceFinish();		

	MATAnimationManager::Instance().ForceFinish();

	//MATLogicBoard::Instance().Clear();
	return gameflow::UIState::OnExit();
}


bool	GENGameState::Tick(float dt)
{
//#ifdef _DEBUG
    
    if(dt > 0)
    {
       
        m_FPSTemp++;
        m_FPSCounter.Tick(dt);
        if(m_FPSCounter.IsReady())
        {
            m_FPSCounter.Reset();
            m_FPS = m_FPSTemp;
            m_FPSTemp = 0;
        }

    }
//#endif

	if(m_pGame)
		m_pGame->Tick(dt);

	for(int i = 0; i < (int)m_pButtons.size(); i++)
	{
		m_pButtons[i]->Tick(dt);
	}

	return gameflow::UIState::Tick(dt);
	
} 

bool	GENGameState::PreRender()
{
#ifdef _DEBUG
	//FontManager::Instance().Print(math::Vec2(0.1f,0.05f), "%i", m_FPS+1);
#endif

	if(m_pGame)
	{
		m_pGame->Render();
	}

	if(m_IsDebugging && m_pGame)
		m_pGame->RenderDebug();
	return UIState::PreRender();
}

bool		GENGameState::PostRender()
{

	if(m_pGame)
		m_pGame->PostRender();

	return UIState::PostRender();
}




void		GENGameState::KeyDown(input::Keyboard::KEY* pKey)
{
	
	
}

void		GENGameState::KeyPressed(input::Keyboard::KEY* pKey)
{

	switch (pKey->KeyID)
	{
	case KEY_D:
		m_IsDebugging = !m_IsDebugging;
		break;

	default:break;
	}

	if(MATUIPopupAnimatorMgr::Instance().KeyPressed(pKey))
	{
		// taken
	}	
	else if(m_pGame)
	{		
		MATUIPopupAnimatorMgr::Instance().Show(MATUIPopupAnimatorMgr::POPUP_NAMES_PAUSEMENU);			
		m_pGame->KeyPressed(pKey);	
	}
}


void		GENGameState::MouseMove(const math::Vec2& From, const math::Vec2& To)
{
	if(m_pGame)
		m_pGame->MouseMove(From, To);
}

void	GENGameState::MouseButtonReleased(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	if(gameflow::UIPopupManager::Instance().GetActivePopup())
		return;
	
	if(m_pGame)
		m_pGame->MouseButtonReleased(pKey, Pos);	
}

void	GENGameState::MouseButtonPressed(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	if(gameflow::UIPopupManager::Instance().GetActivePopup())
		return;

	if(m_pGame)
		m_pGame->MouseButtonPressed(pKey, Pos);	
}

void	GENGameState::MouseButtonDown(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	if(gameflow::UIPopupManager::Instance().GetActivePopup())
		return;

	if(m_pGame)
		m_pGame->MouseButtonDown(pKey, Pos);
}

void	GENGameState::MouseWheelMove(int WheelInfo, const math::Vec2& Pos)
{
	if(m_pGame)
		m_pGame->MouseWheelMove(WheelInfo, Pos);
}

GENGameState* GENGameState::GetGame()
{
	gameflow::GameFlowManager&	Game = gameflow::GameFlowManager::Instance();
	GENGameState*	pGame = (GENGameState*)Game.GetStateByName("game");
	assert(pGame && "No valid Game state!");
	return pGame;
}


void	GENGameState::Load(const std::string& File)
{
	if(m_pGame)
	{
		
		m_pGame->Load(File); 
	}
	else
	{	
		// game is not created yet. so, store it to load it later
		m_FileToLoad = File;
	}
}

void	GENGameState::Save(const std::string& File)
{
	if(m_pGame)
		m_pGame->Save(File); 
}


static background::BGEditor* GetBGEditor()
{	
/*	gameflow::GameFlowManager&	Game = gameflow::GameFlowManager::Instance();
	GENGameState*	pGame = (GENGameState*)Game.GetStateByName("game");
	GENMapState*	pMap = (GENMapState*)Game.GetStateByName("map");
	gameflow::UIState*	pMenu = (gameflow::UIState*)Game.GetStateByName("MainMenu");


	if (Game.GetCurrentState()==pMap)
	{
		return pMap->GetBG().GetEditor();
	}
	if (Game.GetCurrentState()==pMenu)
	{
		return pMenu->GetBG().GetEditor();
	}
	GENGameWorld*	pWorld = GENGameState::GetWorld();
	if (pWorld)
	{
		if (pWorld->GetBG().GetEditor())	return pWorld->GetBG().GetEditor();
		if (pWorld->GetParallaxBG().GetEditor())	return pWorld->GetParallaxBG().GetEditor();
	}*/
	return background::BGEditor::s_pBGEditor;
}

void GENGameState::Register(LuaPlus::LuaState* _pScript)
{

}



void		GENGameState::LoseFocus()
{
	
	gameflow::UIState::LoseFocus();	
}


MATGame*	GENGameState::GetGameMatch5()
{
	return m_pGame;
}

void DELEGATE_CALL		GENGameState::OnButtonPause(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	MATUIPopupAnimatorMgr::Instance().Show(MATUIPopupAnimatorMgr::POPUP_NAMES_PAUSEMENU);
}
	
void DELEGATE_CALL		GENGameState::OnButtonAchievement(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	MATUIPopupAnimatorMgr::Instance().Show(MATUIPopupAnimatorMgr::POPUP_NAMES_ACHIEVEMENT);
}
